﻿'''
题目描述
推荐多样性需要从多个列表中选择元素，一次性要返回 N 屏数据（窗口数量），每屏展示 K 个元素（窗口大小），选择策略：
各个列表元素需要做穿插处理，即先从第一个列表中为每屏选择一个元素，再从第二个列表中为每屏选择一个元素，依次类推
每个列表的元素尽量均分为 N 份，如果不够 N 个，也要全部分配完，参考样例图：
（1）从第一个列表中选择 4 条 0 1 2 3，分别放到 4 个窗口中
（2）从第二个列表中选择 4 条 10 11 12 13，分别放到 4 个窗口中
（3）从第三个列表中选择 4 条 20 21 22 23，分别放到 4 个窗口中
（4）再从第一个列表中选择 4 条 4 5 6 7，分别放到 4 个窗口中
…
（5）再从第一个列表中选择，由于数量不足 4 条，取剩下的 2 条，放到 窗口1 和 窗口2
（6）再从第二个列表中选择，由于数量不足 4 条并且总的元素数达到窗口要求，取 18 19 放到 窗口3 和 窗口4
在这里插入图片描述
输入描述
第一行输入为 N，表示需要输出的窗口数量，取值范围 [1, 10]
第二行输入为 K，表示每个窗口需要的元素数量，取值范围 [1, 100]
之后的行数不定（行数取值范围 [1, 10]），表示每个列表输出的元素列表。元素之间以空格隔开，已经过排序处理，每个列表输出
的元素数量取值范围 [1, 100]
输出描述
输出元素列表，元素数量 = 窗口数量 * 窗口大小，元素之间以空格分隔，多个窗口合并为一个列表输出，参考样例：
先输出窗口1的元素列表，再输出窗口2的元素列表，再输出窗口3的元素列表，最后输出窗口4的元素列表
备注
每个列表会保证元素数量满足窗口要求，不需要考虑元素不足情况
每个列表的元素已去重，不需要考虑元素重复情况
每个列表的元素列表均不为空，不需要考虑列表为空的情况
每个列表的元素列表已经过排序处理，输出结果要保证不改变同一个列表的元素顺序
每个列表的元素数量可能是不同的
用例
输入
4
7
0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
输出
0 10 20 4 14 24 8 1 11 21 5 15 25 9 2 12 22 6 16 26 18 3 13 23 7 17 27 19
解题思路
题目描述的核心是实现一个特定的元素选择和分配策略，以确保从多个列表中选取的元素能够满足给定的输出要求。具体来说，需要从
多个输入列表中选择元素，将这些元素分配到指定数量的窗口中，每个窗口展示固定数量的元素。选择和分配元素时，需要遵循以下规则：
穿插处理：元素的选择需要按照列表的顺序依次进行，即先从第一个列表中选择元素填充到每个窗口中，然后是第二个列表，以此类推。
这样做的目的是确保输出的元素列表能够反映出输入列表的多样性。
均分元素：每个列表中的元素需要尽可能均匀地分配到所有窗口中。如果某个列表的元素不足以在所有窗口中均匀分配，那么这些元素
仍然需要全部被分配出去，直到该列表的元素耗尽。
保持顺序：在选择和分配元素时，需要保持每个列表中元素的原始顺序不变。这意味着不能对列表中的元素进行排序或重新排列。
满足窗口要求：最终输出的元素数量等于窗口数量乘以每个窗口的大小。输出的元素列表是通过将所有窗口的元素合并成一个列表来实现
的，且需要按照窗口的顺序进行合并。
首先读取窗口数量和每个窗口的大小，然后读取每个列表的元素并将其存储在队列中。接着，代码通过循环遍历队列列表，按照规定的
规则从队列中选择元素并将它们分配到一个数组中。这个数组最终被用来构建和输出最终的元素列表。在选择和分配过程中，代码确保了
元素的选择是穿插进行的，每个列表中的元素被均匀分配，且保持了元素的原始顺序。最终，代码输出的元素列表满足了题目的所有要求
'''
#读取输入
win_num = int(input())
element_per_win = int(input())
element_list = []
n = 0
while True:
    try:
        element_list.append(list(map(int,input().split())))
    except:
        break

#定义添加到每个窗口元素的列表
element_add_to_wins = [0] * (win_num * element_per_win)
#遍历元素列表，并添加到每个窗口,利用index,因为列表元素添加完后会被删除(都不能使用，因为列表会被删，index会变化，而且每次不是从
#index=0列表开始)
#使用当窗口元素被填满时
current_index = 0   #用于标记当前填充到窗口列表的位置
queue_index = 0     #用于标记当前处理的队列索引
while current_index < (win_num * element_per_win):
    is_remove_queue = False     #标记本轮是否有队列被移除
    #遍历每个窗口，并尝试从当前队列中为每个窗口提取元素
    for i in range(win_num):
        #如果总队列为空
        if not element_list:
            break
        #如果当前队列为空
        if not element_list[queue_index]:
            #删除当前队列,（添加完元素后，刚好够窗口要求，队列可能为空，但未被删除）
            element_list.pop(queue_index)
            #总队列为空
            if not element_list:
                break
            #更新队列索引，因为删除了队列
            queue_index %= len(element_list)
            is_remove_queue = True
        #如果当前队列不空
        if element_list[queue_index]:
            #向当前窗口添加元素
            element_add_to_wins[current_index] = element_list[queue_index].pop(0)
            current_index += 1  #更新索引
            #判断窗口是否填满，即索引是否超过最大
            if current_index >= len(element_add_to_wins):
                break
    #如果本轮没有队列删除，并且元素列表不为空，则处理下一个队列
    if not is_remove_queue and element_list:
        queue_index = (queue_index + 1) % len(element_list)
#输出结果，按每个窗口输出，即按列输出
for i in range(win_num):
    for j in range(element_per_win):
        print(element_add_to_wins[i + j * win_num],end= ' ')

